package com.iwdnb.gkgz.common.quota;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

import com.alibaba.fastjson.JSON;

import com.google.common.collect.Lists;
import com.iwdnb.gkgz.common.model.dto.StockDayData;
import com.iwdnb.gkgz.common.utils.BigDecimalUtils;
import com.iwdnb.gkgz.common.utils.StockUtils;

/**
 * 量比（Volume Ratio, VR）是衡量一个时间段内成交量变化的指标。它通常用于衡量当前交易日的成交量相对过去几个交易日的平均成交量的变化情况。一般的计算方法是：
 * 量比=当前成交量/过去N日成交量的平均值
 */
public class VolumeRatioIndicator {

    public static final String QUOTA_NAME = "volumeRatio";
    private static final Integer PERIOD = 10;

    public static void calculateVolumeRatio(List<StockDayData> stockDayDataList) {
        calculateVolumeRatio(stockDayDataList, PERIOD, 2);
    }

    public static void calculateVolumeRatio(List<StockDayData> stockDayDataList, int scale) {
        calculateVolumeRatio(stockDayDataList, PERIOD, scale);
    }

    public static void calculateVolumeRatio(List<StockDayData> stockDayDataList, int period, int scale) {
        if (stockDayDataList == null || stockDayDataList.size() < period + 1) {
            return;
        }
        List<Double> volumeRatios = doCalculateVolumeRatio(stockDayDataList, period);
        int size = stockDayDataList.size();
        for (int i = 0; i < size; i++) {
            StockDayData data = stockDayDataList.get(i);
            double ratio = volumeRatios.get(i);
            if (!Double.isInfinite(ratio) && !Double.isNaN(ratio)) {
                StockUtils.setStockQuota(data, QUOTA_NAME, BigDecimalUtils.of(ratio, scale));
            }
        }

    }

    public static List<Double> doCalculateVolumeRatio(List<StockDayData> stockDataList, int period) {
        List<Double> volumeRatioList = new ArrayList<>();
        if (stockDataList == null || stockDataList.size() < period) {
            return volumeRatioList; // 缺乏足够的数据来计算量比
        }

        for (int i = period; i < stockDataList.size(); i++) {
            double avgVolume = 0.0;
            for (int j = i - period; j < i; j++) {
                avgVolume += stockDataList.get(j).getTradeNum();
            }
            avgVolume /= period;
            if (avgVolume == 0) {
                avgVolume = 1;
            }
            double volumeRatio = (double)stockDataList.get(i).getTradeNum() / avgVolume;
            volumeRatioList.add(volumeRatio);
        }

        // 前面的period个时间点没有量比值，因此使用1填充
        for (int i = 0; i < period; i++) {
            volumeRatioList.add(0, 1d);
        }

        return volumeRatioList;
    }

    public static void main(String[] args) {
        // 示例数据，实际数据应该从文件或数据库获取
        List<StockDayData> stockDayDataList = Lists.newArrayList(createStockDayData("ABC", "Stock A", 1000),
            createStockDayData("ABC", "Stock A", 1200), createStockDayData("ABC", "Stock A", 1300),
            createStockDayData("ABC", "Stock A", 1100), createStockDayData("ABC", "Stock A", 1500),
            createStockDayData("ABC", "Stock A", 1400), createStockDayData("ABC", "Stock A", 1600),
            createStockDayData("ABC", "Stock A", 1700), createStockDayData("ABC", "Stock A", 1800),
            createStockDayData("ABC", "Stock A", 1900), createStockDayData("ABC", "Stock A", 2000),
            createStockDayData("ABC", "Stock A", 2100), createStockDayData("ABC", "Stock A", 2200),
            createStockDayData("ABC", "Stock A", 2300), createStockDayData("ABC", "Stock A", 2400));

        int period = 10; // 计算10周期量比
        calculateVolumeRatio(stockDayDataList, period);
        System.out.println("量比: " + JSON.toJSONString(stockDayDataList));
    }

    private static StockDayData createStockDayData(String code, String name, int tradeNum) {
        StockDayData stockDayInfo = new StockDayData();
        stockDayInfo.setCode(code);
        stockDayInfo.setName(name);
        stockDayInfo.setTradeNum(tradeNum);
        return stockDayInfo;
    }
}

